<template>
  <el-dialog
    v-model="dialogVisible"
    title="热门敏感词统计"
    width="800px"
    :before-close="handleClose"
  >
    <div class="popular-words">
      <!-- 查询条件 -->
      <el-card class="query-card">
        <el-form :inline="true" :model="queryForm">
          <el-form-item label="返回数量">
            <el-input-number
              v-model="queryForm.limit"
              :min="5"
              :max="100"
              controls-position="right"
              style="width: 120px"
            />
          </el-form-item>
          <el-form-item label="统计天数">
            <el-input-number
              v-model="queryForm.days"
              :min="1"
              :max="365"
              controls-position="right"
              style="width: 120px"
            />
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              :loading="loading"
              @click="loadPopularWords"
            >
              <el-icon><Search /></el-icon>
              查询
            </el-button>
          </el-form-item>
        </el-form>
      </el-card>

      <!-- 热门敏感词列表 -->
      <el-card class="list-card">
        <template #header>
          <div class="card-header">
            <span>热门敏感词排行榜</span>
            <span class="subtitle">
              (近{{ queryForm.days }}天，前{{ queryForm.limit }}名)
            </span>
          </div>
        </template>

        <div v-loading="loading" class="words-list">
          <div v-if="popularWords.length === 0 && !loading" class="empty-state">
            <el-empty description="暂无数据" />
          </div>

          <div v-else class="words-grid">
            <div
              v-for="(word, index) in popularWords"
              :key="word.id"
              class="word-item"
              :class="getRankClass(index)"
            >
              <div class="rank-badge">
                <span class="rank-number">{{ index + 1 }}</span>
                <el-icon v-if="index < 3" class="rank-icon">
                  <Trophy v-if="index === 0" />
                  <Medal v-else />
                </el-icon>
              </div>

              <div class="word-content">
                <div class="word-header">
                  <span class="word-text">{{ word.word }}</span>
                  <el-tag
                    size="small"
                    :style="{
                      backgroundColor: getTypeColor(word.type),
                      color: '#ffffff',
                      border: 'none'
                    }"
                  >
                    {{ getTypeDescription(word.type) }}
                  </el-tag>
                </div>

                <div class="word-stats">
                  <div class="stat-item">
                    <el-icon><View /></el-icon>
                    <span
                      >匹配次数: {{ word.matchCount.toLocaleString() }}</span
                    >
                  </div>
                  <div class="stat-item">
                    <el-icon><Clock /></el-icon>
                    <span>最后匹配: {{ formatTime(word.lastMatchTime) }}</span>
                  </div>
                </div>

                <div class="word-actions">
                  <el-button
                    type="primary"
                    size="small"
                    link
                    @click="handleViewDetail(word)"
                  >
                    查看详情
                  </el-button>
                  <el-button
                    type="warning"
                    size="small"
                    link
                    @click="handleEdit(word)"
                  >
                    编辑
                  </el-button>
                </div>
              </div>
            </div>
          </div>
        </div>
      </el-card>

      <!-- 统计图表 -->
      <el-card class="chart-card">
        <template #header>
          <span>匹配次数分布</span>
        </template>
        <div ref="chartRef" class="chart-container" />
      </el-card>
    </div>

    <template #footer>
      <div class="dialog-footer">
        <el-button @click="handleClose">关闭</el-button>
        <el-button type="primary" @click="handleExport">
          <el-icon><Download /></el-icon>
          导出数据
        </el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, reactive, computed, onMounted, nextTick } from "vue";
import { ElMessage } from "element-plus";
import {
  Search,
  View,
  Clock,
  Download,
  Trophy,
  Medal
} from "@element-plus/icons-vue";
import * as echarts from "echarts";
import {
  getPopularSensitiveWordsApi,
  type PopularSensitiveWord,
  SensitiveWordManagementUtils
} from "@/api/sensitive-word-management";

// Props
interface Props {
  visible: boolean;
}

const props = defineProps<Props>();

// Emits
const emit = defineEmits<{
  "update:visible": [value: boolean];
  "view-detail": [word: PopularSensitiveWord];
  "edit-word": [word: PopularSensitiveWord];
}>();

// 响应式数据
const dialogVisible = computed({
  get: () => props.visible,
  set: value => emit("update:visible", value)
});

const loading = ref(false);
const chartRef = ref<HTMLElement>();
const chart = ref<echarts.ECharts>();

const queryForm = reactive({
  limit: 20,
  days: 30
});

const popularWords = ref<PopularSensitiveWord[]>([]);

// 加载热门敏感词
const loadPopularWords = async () => {
  try {
    loading.value = true;

    const response = await getPopularSensitiveWordsApi(
      queryForm.limit,
      queryForm.days
    );

    if (response.code === 200) {
      popularWords.value = response.data;
      await nextTick();
      updateChart();
    } else {
      ElMessage.error(response.message || "加载失败");
    }
  } catch (error) {
    console.error("加载热门敏感词失败:", error);
    ElMessage.error("加载失败");
  } finally {
    loading.value = false;
  }
};

// 初始化图表
const initChart = () => {
  if (!chartRef.value) return;

  chart.value = echarts.init(chartRef.value);
  updateChart();
};

// 更新图表
const updateChart = () => {
  if (!chart.value || popularWords.value.length === 0) return;

  const option = {
    title: {
      text: "热门敏感词匹配次数",
      left: "center"
    },
    tooltip: {
      trigger: "axis",
      axisPointer: {
        type: "shadow"
      }
    },
    xAxis: {
      type: "category",
      data: popularWords.value.map(word => word.word),
      axisLabel: {
        rotate: 45,
        interval: 0
      }
    },
    yAxis: {
      type: "value",
      name: "匹配次数"
    },
    series: [
      {
        name: "匹配次数",
        type: "bar",
        data: popularWords.value.map(word => word.matchCount),
        itemStyle: {
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: "#83bff6" },
            { offset: 0.5, color: "#188df0" },
            { offset: 1, color: "#188df0" }
          ])
        }
      }
    ]
  };

  chart.value.setOption(option);
};

// 获取排名样式类
const getRankClass = (index: number) => {
  if (index === 0) return "rank-first";
  if (index === 1) return "rank-second";
  if (index === 2) return "rank-third";
  return "";
};

// 工具函数
const getTypeDescription = (type: string) => {
  return SensitiveWordManagementUtils.getTypeDescription(type as any);
};

const getTypeColor = (type: string) => {
  return SensitiveWordManagementUtils.getTypeColor(type as any);
};

const formatTime = (time: string) => {
  return new Date(time).toLocaleString();
};

// 事件处理
const handleViewDetail = (word: PopularSensitiveWord) => {
  emit("view-detail", word);
};

const handleEdit = (word: PopularSensitiveWord) => {
  emit("edit-word", word);
};

const handleExport = () => {
  // 导出热门敏感词数据
  const data = popularWords.value.map((word, index) => ({
    排名: index + 1,
    敏感词: word.word,
    类型: getTypeDescription(word.type),
    匹配次数: word.matchCount,
    最后匹配时间: formatTime(word.lastMatchTime)
  }));

  const csv = [
    Object.keys(data[0]).join(","),
    ...data.map(row => Object.values(row).join(","))
  ].join("\n");

  const blob = new Blob([csv], { type: "text/csv;charset=utf-8;" });
  const link = document.createElement("a");
  link.href = URL.createObjectURL(blob);
  link.download = `热门敏感词_${new Date().toISOString().split("T")[0]}.csv`;
  link.click();
};

const handleClose = () => {
  dialogVisible.value = false;
};

// 生命周期
onMounted(() => {
  if (props.visible) {
    loadPopularWords();
    nextTick(() => {
      initChart();
    });
  }
});

// 监听对话框显示
computed(() => {
  if (props.visible && popularWords.value.length === 0) {
    loadPopularWords();
    nextTick(() => {
      initChart();
    });
  }
});
</script>

<style scoped>
.popular-words {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.query-card {
  border-radius: 8px;
}

.list-card,
.chart-card {
  border-radius: 8px;
}

.card-header {
  display: flex;
  gap: 8px;
  align-items: center;
}

.subtitle {
  font-size: 12px;
  font-weight: normal;
  color: #909399;
}

.words-list {
  min-height: 300px;
}

.empty-state {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 200px;
}

.words-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(350px, 1fr));
  gap: 16px;
}

.word-item {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  padding: 16px;
  border: 1px solid #ebeef5;
  border-radius: 8px;
  transition: all 0.3s;
}

.word-item:hover {
  border-color: #409eff;
  box-shadow: 0 2px 8px rgb(64 158 255 / 10%);
}

.word-item.rank-first {
  background: linear-gradient(135deg, #fff9e6 0%, #fff 100%);
  border-color: #ffd700;
}

.word-item.rank-second {
  background: linear-gradient(135deg, #f5f5f5 0%, #fff 100%);
  border-color: #c0c0c0;
}

.word-item.rank-third {
  background: linear-gradient(135deg, #fdf2e9 0%, #fff 100%);
  border-color: #cd7f32;
}

.rank-badge {
  display: flex;
  flex-direction: column;
  gap: 4px;
  align-items: center;
  min-width: 40px;
}

.rank-number {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 24px;
  height: 24px;
  font-size: 12px;
  font-weight: bold;
  color: white;
  background: #409eff;
  border-radius: 50%;
}

.rank-first .rank-number {
  color: #333;
  background: #ffd700;
}

.rank-second .rank-number {
  color: #333;
  background: #c0c0c0;
}

.rank-third .rank-number {
  color: white;
  background: #cd7f32;
}

.rank-icon {
  font-size: 16px;
  color: #ffd700;
}

.word-content {
  display: flex;
  flex: 1;
  flex-direction: column;
  gap: 8px;
}

.word-header {
  display: flex;
  gap: 8px;
  align-items: center;
  justify-content: space-between;
}

.word-text {
  font-size: 16px;
  font-weight: 600;
  color: #303133;
}

.word-stats {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-item {
  display: flex;
  gap: 4px;
  align-items: center;
  font-size: 12px;
  color: #606266;
}

.word-actions {
  display: flex;
  gap: 8px;
  margin-top: 4px;
}

.chart-container {
  width: 100%;
  height: 300px;
}

.dialog-footer {
  text-align: right;
}
</style>
